package com.competitions.videoedithelper.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.competitions.videoedithelper.dao.*;
import com.competitions.videoedithelper.entity.*;
import com.competitions.videoedithelper.service.VideoProcessService;
import com.competitions.videoedithelper.utils.AudioUtil;
import com.competitions.videoedithelper.utils.FileUtil;
import com.competitions.videoedithelper.utils.StreamUtil;
import com.competitions.videoedithelper.utils.UploadFileUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Random;
import java.util.UUID;

/**
 * @author 盛旭雯
 */
@Service
public class VideoProcessServiceImpl implements VideoProcessService {
    private AudioInfoDao audioInfoDao;
    private VideoInfoDao videoInfoDao;
    private AudioSegmentDao audioSegmentDao;
    private IOperationHistoryDao iOperationHistoryDao;
    private NewVideoDao newVideoDao;

    @Autowired
    public VideoProcessServiceImpl(AudioInfoDao audioInfoDao, VideoInfoDao videoInfoDao, AudioSegmentDao audioSegmentDao,IOperationHistoryDao iOperationHistoryDao,NewVideoDao newVideoDao) {
        this.audioInfoDao = audioInfoDao;
        this.videoInfoDao = videoInfoDao;
        this.audioSegmentDao = audioSegmentDao;
        this.iOperationHistoryDao = iOperationHistoryDao;
        this.newVideoDao=newVideoDao;
    }

    @Override
    public ResponseModel extractAudio(int videoId) {
        VideoInfo videoInfo=videoInfoDao.selectVideo(videoId);
        if(videoInfo==null){
            return new ResponseModel(178,"源视频文件不存在");
        }else {
            String name=videoInfo.getName();
            String videoPath=videoInfo.getFilePath();

            //String ffmpegPath="C:\\video_edit_helper\\lib\\ffmpeg\\bin\\ffmpeg.exe";
            String ffmpegPath="/usr/bin/ffmpeg";
            String codeName=videoPath.substring(videoPath.lastIndexOf("/")+1,videoPath.lastIndexOf("."));
            String audioName=codeName+".wav";
            //String audioPathDir="C:/uploadTest/audios/";
            String audioPathDir="/root/home/userfiles/audios/"+codeName+"/";
            String audioPath=audioPathDir+audioName;
            File audio=new File(audioPath);
            if(audio.exists()){
                return new ResponseModel(200,"提取音频成功",audioInfoDao.selectAudio2(videoId,0));
            }
            File aFile=new File(audioPathDir);
            String remotePath="http://121.43.142.18:8066/userfiles/audios/"+codeName+"/"+audioName;
            String command=ffmpegPath+" -i "+videoPath+" -ac 1 -ar 16000 "+audioPath;
            System.out.println("video to audio command : " + command);

            boolean isCreateSuccess = true;
            if (!aFile.exists()) {
                isCreateSuccess=aFile.mkdirs();
            }
            if(!isCreateSuccess){
                System.out.println("创建文件夹失败");
                return new ResponseModel(177,"创建文件夹失败");
            }
            try {
                Process process = Runtime.getRuntime().exec(command);
                StreamUtil.dealStream(process);
                process.waitFor();
                if(!audio.exists()){
                    return new ResponseModel(165,"提取音频失败");
                }
                long audioSize=audio.length();
                Timestamp generTime = new Timestamp(System.currentTimeMillis());
                int audioDuration=(int) AudioUtil.getAudioTime(audio);
                String time=UploadFileUtil.getTime(audioDuration);
                AudioInfo audioInfo=new AudioInfo();
                audioInfo.setName(name);
                audioInfo.setAudioSize(audioSize+"");
                audioInfo.setGenerTime(generTime);
                audioInfo.setAudioTime(time);
                audioInfo.setAudioDuration(audioDuration);
                audioInfo.setVideoId(videoId);
                audioInfo.setAudioType(".wav");
                audioInfo.setFilePath(audioPath);
                audioInfo.setPriorId(0);
                audioInfo.setRemotePath(remotePath);
                audioInfoDao.insertAudioInfo(audioInfo);
                return new ResponseModel(200,"提取音频成功",audioInfo);
            } catch (Exception e) {
                e.printStackTrace();
                return new ResponseModel(178,"源视频文件不存在");
            }
        }
    }

    @Override
    public ResponseModel modifyAudio(int audioId, MultipartFile part, String begin, String end) {
        AudioInfo audioInfo=audioInfoDao.selectAudio(audioId);
        if(audioInfo==null){
            return new ResponseModel(161,"上一步音频文件不存在");
        }else{
            String audioPath=audioInfo.getFilePath();
            String remotePath=audioInfo.getRemotePath();
            String mp3Path=audioPath.substring(0,audioPath.lastIndexOf("."))+".mp3";
            File mp3=new File(mp3Path);
            if(!mp3.exists()){
                mp3Path=AudioUtil.wavToMp3(audioPath);
            }
            if(mp3Path==null){
                return new ResponseModel(162,"音频格式转换失败");
            }else {
                File[] files=null;
                String audioPathDir=audioPath.substring(0,audioPath.lastIndexOf("/"))+"/";
                String remotePathDir=remotePath.substring(0,remotePath.lastIndexOf("/"))+"/";
                int audioDuration=audioInfo.getAudioDuration();
                String[] paths=AudioUtil.cutAudio(mp3Path,audioDuration,begin,end,audioPathDir);
                if (paths==null){
                    return new ResponseModel(163,"截取音频失败");
                }
                File file1=null;
                if (paths[0]!=null){
                   file1 =new File(paths[0]);
                }
                File file3=new File(paths[1]);

                String name2=part.getOriginalFilename();
                assert name2 != null;
                name2=UUID.randomUUID()+name2.substring(name2.lastIndexOf("."));
                String partPath=audioPathDir+name2;
                String mp3Part=partPath.substring(0,partPath.lastIndexOf("."))+".mp3";
                partPath=AudioUtil.transAudio(part,partPath);
                if (partPath==null){
                    files= new File[]{file1, file3};
                    FileUtil.deleteFiles(files);
                    return new ResponseModel(164,"转存音频失败");
                }
                if(!partPath.equals(mp3Part)){
                    mp3Part=AudioUtil.wavToMp3(partPath);
                    File file=new File(partPath);
                    FileUtil.deleteFile(file);
                }
                if(mp3Part==null) {
                    files= new File[]{file1, file3};
                    FileUtil.deleteFiles(files);
                    return new ResponseModel(162, "音频格式转换失败");
                }

                String path4=AudioUtil.pieceAudio(paths[0],mp3Part,paths[1],audioPathDir);
                Timestamp generTime = new Timestamp(System.currentTimeMillis());
                File file2=new File(mp3Part);
                files= new File[]{file1,file2,file3};
                FileUtil.deleteFiles(files);
                if(path4==null){
                    return new ResponseModel(166,"修改音频失败");
                }

                File file4=new File(path4);
                String name4=path4.substring(path4.lastIndexOf("/")+1,path4.lastIndexOf("."));
                long audioSize=file4.length();
                int file4Duration=AudioUtil.getMp3Length(file4);
                String time= UploadFileUtil.getTime(file4Duration);
                AudioInfo audio=new AudioInfo();
                audio.setName(name4);
                audio.setAudioSize(audioSize+"");
                audio.setGenerTime(generTime);
                audio.setAudioTime(time);
                audio.setAudioDuration(file4Duration);
                audio.setVideoId(audioInfo.getVideoId());
                audio.setAudioType(".mp3");
                audio.setFilePath(path4);
                audio.setPriorId(audioId);
                audio.setRemotePath(remotePathDir+name4+".mp3");
                try {
                    audioInfoDao.insertAudioInfo(audio);
                    return new ResponseModel(200,"修改音频成功",audio);
                }catch (Exception e){
                    return new ResponseModel(166,"修改音频失败");
                }
            }
        }
    }

    @Override
    public ResponseModel modifyAudioSeg(int sourceId, String begin1, String end1, MultipartFile part, String begin2, String end2) {
        AudioInfo audioInfo=audioInfoDao.selectAudio(sourceId);
        if(audioInfo==null){
            return new ResponseModel(161,"源音频文件不存在");
        }else{
            String audioPath=audioInfo.getFilePath();
            String mp3Path=audioPath.substring(0,audioPath.lastIndexOf("."))+".mp3";
            File mp3=new File(mp3Path);
            if(!mp3.exists()){
                mp3Path=AudioUtil.wavToMp3(audioPath);
            }
            if(mp3Path==null){
                return new ResponseModel(162,"音频格式转换失败");
            }else {
                File[] files=null;
                //String audioPathDir="C:/uploadTest/temp/";
                String audioPathDir="/root/home/userfiles/audios/temp/";
                String segPath=AudioUtil.cutAudio2(mp3Path,begin1,end1,audioPathDir);
                if (segPath==null){
                    return new ResponseModel(163,"截取音频失败");
                }
                File file0=new File(segPath);

                int len1=UploadFileUtil.getTimelen(begin1);
                int len2=UploadFileUtil.getTimelen(begin2);
                String duration1=UploadFileUtil.getTime(len2-len1);
                int len3=UploadFileUtil.getTimelen(end1);
                int len4=UploadFileUtil.getTimelen(end2);
                String end=UploadFileUtil.getTime(len4-len1);
                String[] paths=AudioUtil.cutAudio(segPath,len3-len1,duration1,end,audioPathDir);
                if (paths==null){
                    FileUtil.deleteFile(file0);
                    return new ResponseModel(163,"截取音频失败");
                }
                File file1=null;
                if(paths[0]!=null){
                    file1=new File(paths[0]);
                }
                File file3=new File(paths[1]);

                String name2=part.getOriginalFilename();
                assert name2 != null;
                name2=UUID.randomUUID()+name2.substring(name2.lastIndexOf("."));
                String partPath=audioPathDir+name2;
                String mp3Part=partPath.substring(0,partPath.lastIndexOf("."))+".mp3";
                partPath=AudioUtil.transAudio(part,partPath);
                if (partPath==null){
                    files= new File[]{file0,file1, file3};
                    FileUtil.deleteFiles(files);
                    return new ResponseModel(164,"转存音频失败");
                }
                if(!partPath.equals(mp3Part)){
                    mp3Part=AudioUtil.wavToMp3(partPath);
                    File file=new File(partPath);
                    FileUtil.deleteFile(file);
                }
                if(mp3Part==null) {
                    files= new File[]{file0, file1, file3};
                    FileUtil.deleteFiles(files);
                    return new ResponseModel(162, "音频格式转换失败");
                }

                String path4=AudioUtil.pieceAudio(paths[0],mp3Part,paths[1],audioPathDir);
                Timestamp generTime = new Timestamp(System.currentTimeMillis());
                File file2=new File(mp3Part);
                files= new File[]{file0, file1, file2, file3};
                FileUtil.deleteFiles(files);
                if(path4==null){
                    return new ResponseModel(166,"修改音频失败");
                }

                File file4=new File(path4);
                String id=FileUtil.getId(20);
                String name4=path4.substring(path4.lastIndexOf("/")+1,path4.lastIndexOf("."));
                long audioSize=file4.length();
                int file4Duration=AudioUtil.getMp3Length(file4);
                String remotePath="http://121.43.142.18:8066/userfiles/audios/temp/"+name4+".mp3";
                AudioSegment audioSegment=new AudioSegment();
                audioSegment.setId(id);
                audioSegment.setName(name4);
                audioSegment.setAudioSize(audioSize+"");
                audioSegment.setGenerTime(generTime);
                audioSegment.setBegin(begin1);
                audioSegment.setEnd(end1);
                audioSegment.setAudioDuration(file4Duration);
                audioSegment.setSourceId(sourceId);
                audioSegment.setAudioType(".mp3");
                audioSegment.setFilePath(path4);
                audioSegment.setRemotePath(remotePath);
                try {
                    audioSegmentDao.insertAudioSegment(audioSegment);
                    return new ResponseModel(200,"修改音频成功",audioSegment);
                }catch (Exception e){
                    return new ResponseModel(166,"修改音频失败");
                }
            }
        }
    }

    @Override
    public ResponseModel cutAudio(int sourceId, String filePath, String begin, String end) {
        //String audioPathDir="C:/uploadTest/temp/";
        String audioPathDir="/root/home/userfiles/audios/temp/";
        String segPath;
        Timestamp generTime;
        if(!".mp3".equals(filePath.substring(filePath.lastIndexOf(".")))){
            String mp3Path=filePath.substring(0,filePath.lastIndexOf("."))+".mp3";
            File mp3=new File(mp3Path);
            if(!mp3.exists()){
                mp3Path=AudioUtil.wavToMp3(filePath);
            }
            if(mp3Path==null){
                return new ResponseModel(162,"音频格式转换失败");
            }else {
                segPath=AudioUtil.cutAudio2(mp3Path,begin,end,audioPathDir);
                generTime = new Timestamp(System.currentTimeMillis());
            }
        }else {
            segPath=AudioUtil.cutAudio2(filePath,begin,end,audioPathDir);
            generTime = new Timestamp(System.currentTimeMillis());
        }
        if (segPath==null){
            return new ResponseModel(163,"截取音频失败");
        }

        File file=new File(segPath);
        String id=FileUtil.getId(20);
        String name=segPath.substring(segPath.lastIndexOf("/")+1,segPath.lastIndexOf("."));
        long audioSize=file.length();
        int file4Duration=AudioUtil.getMp3Length(file);
        String remotePath="http://121.43.142.18:8066/userfiles/audios/temp/"+name+".mp3";
        AudioSegment audioSegment=new AudioSegment();
        audioSegment.setId(id);
        audioSegment.setName(name);
        audioSegment.setAudioSize(audioSize+"");
        audioSegment.setGenerTime(generTime);
        audioSegment.setBegin(begin);
        audioSegment.setEnd(end);
        audioSegment.setAudioDuration(file4Duration);
        audioSegment.setSourceId(sourceId);
        audioSegment.setAudioType(".mp3");
        audioSegment.setFilePath(segPath);
        audioSegment.setRemotePath(remotePath);
        try {
            audioSegmentDao.insertAudioSegment(audioSegment);
            return new ResponseModel(200,"截取音频成功",audioSegment);
        }catch (Exception e){
            e.printStackTrace();
            return new ResponseModel(166,"修改音频失败");
        }
    }

    @Override
    public ResponseModel batchModification(JSONObject data) {
        int audioId;
        try {
            audioId=data.getInteger("audioId");
        }catch (Exception e){
            return new ResponseModel(159,"音频id获取失败");
        }
        AudioInfo audioInfo=audioInfoDao.selectAudio(audioId);
        if(audioInfo==null){
            return new ResponseModel(161,"源音频文件不存在");
        }else{
            String audioPath=audioInfo.getFilePath();
            String mp3Path=audioPath.substring(0,audioPath.lastIndexOf("."))+".mp3";
            File mp3=new File(mp3Path);
            if(!mp3.exists()){
                mp3Path=AudioUtil.wavToMp3(audioPath);
            }
            if(mp3Path==null){
                return new ResponseModel(162,"音频格式转换失败");
            }else {
                String path="";
                File file=null;
                int c=0;
                String audioPathDir=audioPath.substring(0,audioPath.lastIndexOf("/"))+"/";
                int duration=audioInfo.getAudioDuration();
                int videoId = audioInfo.getVideoId();
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String date = simpleDateFormat.format(System.currentTimeMillis());
                String audioUrl = audioInfo.getRemotePath();
                JSONArray jsonArray=data.getJSONArray("data");
                File[] files=new File[jsonArray.size()*4];
                for (int i=0;i<jsonArray.size();i++){
                    JSONObject jsonObject=jsonArray.getJSONObject(i);
                    try {
                        String filePath=jsonObject.getString("filePath");
                        String begin=jsonObject.getString("begin");
                        String end=jsonObject.getString("end");
                        String[] paths=AudioUtil.cutAudio(mp3Path,duration,begin,end,audioPathDir);
                        if(file!=null){
                            files[c++]=file;
                        }
                        if (paths==null){
                            continue;
                        }
                        path=AudioUtil.pieceAudio(paths[0],filePath,paths[1],audioPathDir);
                        if(path==null){
                            continue;
                        }
                        if(paths[0]!=null){
                            files[c++]=new File(paths[0]);
                        }
                        files[c++]=new File(paths[1]);
                        //files[c++]=new File(filePath);
                        file=new File(path);
                        audioPath=path;
                        duration=AudioUtil.getMp3Length(file);
                        iOperationHistoryDao.insertHistory(date,begin, end,audioUrl,videoId);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
                Timestamp generTime = new Timestamp(System.currentTimeMillis());
                FileUtil.deleteFiles(files);
                assert file != null;
                if(!file.exists()){
                    return new ResponseModel(166,"修改音频失败");
                }
                assert path != null;
                String name=path.substring(path.lastIndexOf("/")+1,path.lastIndexOf("."));
                String time= UploadFileUtil.getTime(duration);
                String remotePath=audioInfo.getRemotePath();
                String remotePathDir=remotePath.substring(0,remotePath.lastIndexOf("/"))+"/";
                AudioInfo audio=new AudioInfo();
                audio.setName(name);
                audio.setAudioSize(file.length()+"");
                audio.setGenerTime(generTime);
                audio.setAudioTime(time);
                audio.setAudioDuration(duration);
                audio.setVideoId(audioInfo.getVideoId());
                audio.setAudioType(".mp3");
                audio.setFilePath(path);
                audio.setPriorId(audioId);
                audio.setRemotePath(remotePathDir+name+".mp3");
                try {
                    audioInfoDao.insertAudioInfo(audio);
                    return new ResponseModel(200,"修改音频成功",audio);
                }catch (Exception e){
                    return new ResponseModel(166,"修改音频失败");
                }
            }
        }
    }

    @Override
    public ResponseModel selectEditedAudios(int videoId) {
        return new ResponseModel(200,"成功",audioInfoDao.selectEditedAudioInfos(videoId));
    }

    @Override
    public ResponseModel deleteEditedAudio(int audioId) {
        AudioInfo audioInfo = audioInfoDao.selectAudio(audioId);
        File file = new File(audioInfo.getFilePath());
        if(file.delete()) {
            audioInfoDao.deleteAudioInfo(audioId);
            return new ResponseModel(200, "成功");
        }else {
            return new ResponseModel(199,"删除失败");
        }
    }

    @Override
    public ResponseModel combineVideo(int videoId, String audioPath) {
        VideoInfo videoInfo=videoInfoDao.selectVideo(videoId);
        if (videoInfo==null){
            return new ResponseModel(188,"源视频文件不存在");
        }else {
            int userId=videoInfo.getUploadUserId();
            //String videoPathDir="C:/uploadTest/newVideo/";
            String videoPathDir="/root/home/userfiles/videos/newVideos/"+userId+"/"+videoId+"/";
            if(!FileUtil.createFolder(videoPathDir)){
                return new ResponseModel(190,"创建文件夹失败");
            }
            String initVideoPath=videoInfo.getFilePath();
            String name=UUID.randomUUID()+videoInfo.getVideoType();
            String newVideoPath=videoPathDir+name;
            if(!AudioUtil.combineVideo(initVideoPath,audioPath,newVideoPath)){
                return new ResponseModel(151,"合成视频失败");
            }
            Timestamp generTime = new Timestamp(System.currentTimeMillis());
            File newFile=new File(newVideoPath);
            String videoSize=newFile.length()+"";
            String videoTime="";
            try {
                videoTime=UploadFileUtil.getVideoTime(newVideoPath);
            }catch (Exception e){
                System.out.println("获取时长失败");
            }
            String remotePath="http://121.43.142.18:8066/userfiles/videos/newVideos/"+userId+"/"+videoId+"/"+name;
            NewVideo newVideo=new NewVideo();
            newVideo.setCusName(videoInfo.getCusName());
            newVideo.setName(videoInfo.getName());
            newVideo.setVideoSize(videoSize);
            newVideo.setGenerTime(generTime);
            newVideo.setVideoTime(videoTime);
            newVideo.setImageUrl(videoInfo.getImageUrl());
            newVideo.setInitVideoId(videoId);
            newVideo.setVideoType(videoInfo.getVideoType());
            newVideo.setFilePath(newVideoPath);
            newVideo.setRemotePath(remotePath);

            videoInfo.setVideoSize(videoSize);
            videoInfo.setAddTime(generTime);
            videoInfo.setStatus("");
            videoInfo.setVideoLength("");
            videoInfo.setIdVarchar("");
            videoInfo.setVideoTime(videoTime);
            videoInfo.setFilePath(newVideoPath);
            videoInfo.setRemotePath(remotePath);
            try {
                newVideoDao.insertNewVideo(newVideo);
                videoInfoDao.insertVideoInfo(videoInfo);
                return new ResponseModel(200,"合成视频成功",videoInfo);
            }catch (Exception e){
                return new ResponseModel(150,"插入数据失败");
            }
        }
    }
}
